package cn.iocoder.yudao.module.shop.info.controller.admin;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.business.audit.pojo.form.AuditSaveDTO;
import cn.iocoder.yudao.framework.business.basic.convert.BigDecimalConvert;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.qrcode.pojo.QrCodePaymentType;
import cn.iocoder.yudao.framework.qrcode.util.QrCodeUtils;
import cn.iocoder.yudao.framework.region.RegionUtils;
import cn.iocoder.yudao.framework.region.enums.RegionDataSet;
import cn.iocoder.yudao.module.api.member.assets.MemberDigitalAssetsApi;
import cn.iocoder.yudao.module.api.member.assets.dto.MemberDigitalAssetsRespDTO;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.shop.category.pojo.po.ShopCategory;
import cn.iocoder.yudao.module.shop.category.pojo.vo.ShopCategoryRespVO;
import cn.iocoder.yudao.module.shop.category.service.ShopCategoryService;
import cn.iocoder.yudao.module.shop.info.convert.ShopInfoConvert;
import cn.iocoder.yudao.module.shop.info.dal.dataobject.ShopInfoDO;
import cn.iocoder.yudao.module.shop.info.service.ShopInfoService;
import cn.iocoder.yudao.module.shop.info.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

@Tag(name = "管理后台 - 店铺信息")
@RestController
@RequestMapping("/shop/info")
@Validated
public class ShopInfoController {

    @Resource
    private ShopInfoService shopInfoService;
    @Resource
    private ShopCategoryService shopCategoryService;

    @Resource
    private MemberDigitalAssetsApi memberDigitalAssetsApi;
    @Resource
    private MemberUserApi memberUserApi;

    @PostMapping("/create")
    @Operation(summary = "创建店铺信息")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    public CommonResult<Long> createInfo(@Valid @RequestBody ShopInfoCreateVO createReqVO) {
        Long id = shopInfoService.createInfo(createReqVO);
        return success(id);
    }

    @PostMapping("/update-basic")
    @Operation(summary = "更新基础资料")
    @PreAuthorize("@ss.hasPermission('shop:info:update')")
    public CommonResult<Boolean> updateBasic(@Valid @RequestBody ShopInfoBasicUpdateReqVO reqVO) {
        shopInfoService.updateInfo(reqVO);
        return success(true);
    }

    @PostMapping("/update-address")
    @Operation(summary = "更新经营地址")
    @PreAuthorize("@ss.hasPermission('shop:info:update')")
    public CommonResult<Boolean> updateAddress(@Valid @RequestBody ShopAddressSaveForm reqVO) {
        shopInfoService.updateAddress(reqVO);
        return success(true);
    }

    @PostMapping("/update-category")
    @Operation(summary = "更新主营类目")
    @PreAuthorize("@ss.hasPermission('shop:info:update')")
    public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ShopCategoryUpdateReqVO reqVO) {
        shopInfoService.updateCategory(reqVO);
        return success(true);
    }

    @PostMapping("/update-status")
    @Operation(summary = "更新营业状态")
    @PreAuthorize("@ss.hasPermission('shop:info:update')")
    public CommonResult<Boolean> updateStatus(@Valid @RequestBody ShopStatusUpdateReqVO reqVO) {
        shopInfoService.updateStatus(reqVO);
        return success(true);
    }

    @PostMapping("/update-audit")
    @Operation(summary = "更新审核信息")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    public CommonResult<Boolean> updateAudit(@Valid @RequestBody AuditSaveDTO reqVO) {
        shopInfoService.updateAudit(reqVO);
        return success(true);
    }

    @PostMapping("/update-enabled")
    @Operation(summary = "更新开关")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    public CommonResult<Boolean> updateEnabled(@Valid @RequestBody ShopEnabledSaveVO reqVO) {
        shopInfoService.updateEnabled(reqVO);
        return success(true);
    }

    @PostMapping("/update-enter-package")
    @Operation(summary = "更新入驻套餐信息", description = "免费赠送套餐")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    public CommonResult<Boolean> updateEnterPackage(@Valid @RequestBody ShopEnterPackageUpdateReqVO reqVO) {
        shopInfoService.updateEnterPackage(reqVO);
        return success(true);
    }

    @PostMapping("/update-service-fee")
    @Operation(summary = "更新平台服务费比例")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<Boolean> updateServiceFee(@Valid @RequestBody ShopServiceFeeUpdateReqVO updateReqVO) {
        shopInfoService.updateServiceFee(updateReqVO);
        return success(true);
    }

    @PostMapping("/update-discount-percent")
    @Operation(summary = "更新顾客可抵扣比例")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<Boolean> updateDiscountPercent(@Valid @RequestBody ShopDiscountPercentUpdateReqVO updateReqVO) {
        shopInfoService.updateDiscountPercent(updateReqVO);
        return success(true);
    }

    @GetMapping("/delete")
    @Operation(summary = "删除店铺信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    public CommonResult<Boolean> deleteInfo(@RequestParam("id") Long id) {
        shopInfoService.deleteInfo(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得店铺信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<AdminShopInfoVO> getInfo(@RequestParam("id") Long id) {
        ShopInfoDO shopInfoDO = shopInfoService.getInfo(id);
        if (shopInfoDO == null) {
            return success(null);
        }
        AdminShopInfoVO data = ShopInfoConvert.INSTANCE.convert3(shopInfoDO);
        MemberDigitalAssetsRespDTO digitalAssetsRespDTO = memberDigitalAssetsApi.getDetail(data.getUserId());
        data.setCryptocurrency(digitalAssetsRespDTO.getCryptocurrency());
        data.setCryptocurrencyOrigin(digitalAssetsRespDTO.getCryptocurrencyOrigin());
        data.setCryptocurrencyGet(digitalAssetsRespDTO.getCryptocurrencyGet());
        data.setCryptocurrencyFreezing(digitalAssetsRespDTO.getCryptocurrencyFreezing());
        RegionUtils.autoAssignCounty(RegionDataSet.ONLY_LATEST, data.getCountyCode(), data);
        return success(data);
    }

    @GetMapping("/my")
    @Operation(summary = "获得我的店铺信息")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<ShopInfoVO> getMyInfo() {
        Long shopId = shopInfoService.getShopIdByAdminUserId(getLoginUserId());
        ShopInfoDO shopInfoDO = shopInfoService.getInfo(shopId);
        if (shopInfoDO == null) {
            return success(null);
        }
        ShopInfoVO data = ShopInfoConvert.INSTANCE.convert2(shopInfoDO);
        return success(data);
    }

    @GetMapping("/my-category")
    @Operation(summary = "获得我的店铺主营类目信息")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<ShopCategoryRespVO> getMyCategoryInfo() {
        Long shopId = shopInfoService.getShopIdByAdminUserId(getLoginUserId());
        ShopCategory categoryDO = shopInfoService.getShopCategory(shopId);
        if (categoryDO == null) {
            return success(new ShopCategoryRespVO());
        }
        ShopCategoryRespVO data = BeanUtils.toBean(categoryDO, ShopCategoryRespVO.class);
        return success(data);
    }

    @GetMapping("/page")
    @Operation(summary = "获得店铺信息分页")
    @Parameter(name = "pageNo", description = "页码", required = true, example = "1")
    @Parameter(name = "pageSize", description = "每页数据条数", required = true, example = "10")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<PageResult<AdminShopInfoVO>> getInfoPage(@RequestParam("pageNo") Integer current, @RequestParam("pageSize") Integer size, @Valid AdminShopInfoQueryDTO pageReqVO) {
        PageResult<ShopInfoDO> pageResult = shopInfoService.getInfoPage(current, size, pageReqVO);
        PageResult<AdminShopInfoVO> data = ShopInfoConvert.INSTANCE.convertPage2(pageResult);
        Set<Long> categoryIds = convertSet(data.getList(), AdminShopInfoVO::getCategoryId);
        Map<Long, ShopCategory> categoryMap = shopCategoryService.getCategoryMap(categoryIds);
        Set<Long> userIds = convertSet(data.getList(), AdminShopInfoVO::getUserId);
        Map<Long, UserSimpleVO> users = memberUserApi.getUserSimpleMap(userIds);
        Map<Long, MemberDigitalAssetsRespDTO> digitalAssetMap = memberDigitalAssetsApi.getMapByUserIds(userIds);
        data.getList().forEach(it -> {
            UserSimpleVO userSimpleVO = users.getOrDefault(it.getUserId(), UserSimpleVO.ANONYMOUS);
            it.setUser(userSimpleVO);
            RegionUtils.autoAssignCounty(RegionDataSet.ONLY_LATEST, it.getCountyCode(), it);
            ShopCategory categoryDO = categoryMap.get(it.getCategoryId());
            if (categoryDO != null) {
                it.setCategoryName(categoryDO.getName());
                it.setCategoryCode(categoryDO.getCode());
            }
            MemberDigitalAssetsRespDTO digitalAssetsRespVO = digitalAssetMap.getOrDefault(it.getUserId(), null);
            if (digitalAssetsRespVO == null) {
                it.setCryptocurrency(BigDecimalConvert.INSTANCE.convert(0));
                it.setCryptocurrencyOrigin(BigDecimalConvert.INSTANCE.convert(0));
                it.setCryptocurrencyGet(BigDecimalConvert.INSTANCE.convert(0));
                it.setCryptocurrencyFreezing(BigDecimalConvert.INSTANCE.convert(0));
            } else {
                it.setCryptocurrency(digitalAssetsRespVO.getCryptocurrency());
                it.setCryptocurrencyOrigin(digitalAssetsRespVO.getCryptocurrencyOrigin());
                it.setCryptocurrencyGet(digitalAssetsRespVO.getCryptocurrencyGet());
                it.setCryptocurrencyFreezing(digitalAssetsRespVO.getCryptocurrencyFreezing());
            }
            QrCodePaymentType qrCodePaymentType = new QrCodePaymentType();
            qrCodePaymentType.setShopId(it.getId());
            qrCodePaymentType.setMemberNo(userSimpleVO.getNo());
            it.setQrcodeText(QrCodeUtils.buildUrl(qrCodePaymentType));
            it.setQrcodeImage(QrCodeUtils.generatePngAsBase64Uri(qrCodePaymentType, it.getLogo()));
        });
        return success(data);
    }

    @GetMapping("/search-list")
    @Operation(summary = "搜索店铺简单资料列表")
    @Parameter(name = "keyword", description = "关键词，店铺名称或联系电话", example = "羡民")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<List<ShopInfoSimpleRespVO>> searchInfoList(@RequestParam(name = "keyword") String keyword) {
        List<ShopInfoDO> list = shopInfoService.searchInfoList(keyword);
        return success(ShopInfoConvert.INSTANCE.convertSimpleList(list));
    }

    @GetMapping("/pick-list")
    @Operation(summary = "选择店铺简单资料列表")
    @Parameter(name = "ids", description = "店铺编号集合，多个用英文逗号分隔", example = "1,2")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<List<ShopInfoSimpleRespVO>> pickInfoList(@RequestParam(name = "ids") List<Long> ids) {
        List<ShopInfoDO> list = shopInfoService.pickInfoList(ids);
        return success(ShopInfoConvert.INSTANCE.convertSimpleList(list));
    }

    @GetMapping("/simple-list")
    @Operation(summary = "获得店铺简单资料列表")
    @Parameter(name = "status", description = "状态：0-未开通、1-营业中、2-停业中", example = "1")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin', 'shop_admin')")
    public CommonResult<List<ShopInfoSimpleRespVO>> getInfoSimpleList(@RequestParam(name = "status", required = false) Integer status) {
        List<ShopInfoDO> list = shopInfoService.getInfoList(status);
        return success(ShopInfoConvert.INSTANCE.convertSimpleList(list));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出店铺信息 Excel")
    @PreAuthorize("@ss.hasAnyRoles('super_admin', 'platform_admin', 'tenant_admin')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportInfoExcel(@Valid AdminShopInfoQueryDTO pageReqVO,
                                HttpServletResponse response) throws IOException {
        List<AdminShopInfoVO> list = getInfoPage(1, PageParam.PAGE_SIZE_NONE, pageReqVO).getData().getList();
        // 导出 Excel
        ExcelUtils.write(response, "店铺信息.xls", "数据", AdminShopInfoVO.class, list);
    }

}
